import * as path from "path";
import * as protoLoader from "@grpc/proto-loader";
import * as grpc from "@grpc/grpc-js";
import { GreeterHandlers } from "./proto/helloworld/Greeter";
import { ProtoGrpcType } from "./proto/sample";

async function bootstrap() {
  const exampleServer: GreeterHandlers = {
    SayHello({ request: { name } }, callback) {
      return callback(null, { message: "hello " + name });
    },
    SayHelloC(call, callback) {
      const array: string[] = [];
      call.on("data", (chunk) => {
        console.log("SayHelloC chunk: ", chunk);
        array.push(chunk.name);
      });
      call.on("end", () => {
        callback(null, { message: "hello: " + array.join(", ") });
      });
    },
    SayHelloS(call) {
      const messages = ["abc", "def", "ghi", call.request.name];
      for (const message of messages) {
        call.write({ message });
      }
      call.end();
    },
    SayHelloB(call) {
      call.on("data", (chunk) => {
        console.log("SayHelloB chunk: ", chunk);
        call.write({ message: "hello, " + chunk.name });
      });
      call.on("end", () => {
        call.end();
      });
    },
  };

  const packageDefinition = protoLoader.loadSync(
    path.resolve(__dirname, "./proto/sample.proto"),
    {
      keepCase: true,
      longs: String,
      enums: String,
      defaults: true,
      oneofs: true,
    }
  );

  const proto = grpc.loadPackageDefinition(
    packageDefinition
  ) as unknown as ProtoGrpcType;

  const server = new grpc.Server();
  server.addService(proto.helloworld.Greeter.service, exampleServer);
  server.bindAsync(
    "0.0.0.0:50051",
    grpc.ServerCredentials.createInsecure(),
    () => {
      console.log("On 0.0.0.0:50051");
      server.start();
    }
  );
}
bootstrap();
